package rexsee.core.browser;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;

import rexsee.core.browser.clazz.JavascriptInterface;
import rexsee.core.browser.clazz.PromptArgumentsSheet;
import rexsee.core.lang.RexseeLanguage;
import rexsee.core.menu.PopMenu;
import rexsee.core.menu.PopMenuItem;
import rexsee.core.utilities.Utilities;
import rexsee.core.widget.RatingStars;
import rexsee.core.widget.Slider;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.GradientDrawable;
import android.text.Html;
import android.text.InputFilter;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.TimePicker;

public class RexseePrompt implements JavascriptInterface {

	public static final String INTERFACE_NAME = "Prompt";
	@Override
	public String getInterfaceName() {
		return (mBrowser == null) ? null : mBrowser.application.resources.prefix + INTERFACE_NAME;
	}
	@Override
	public JavascriptInterface getInheritInterface(Browser childBrowser) {
		return childBrowser.promptListeners;
	}
	@Override
	public JavascriptInterface getNewInterface(Browser childBrowser) {
		return new RexseePrompt(childBrowser);
	}

	public static abstract class OnPromptReturnListener {
		public abstract void run(String rtn);
	}
	public static abstract class OnPromptListener {
		public abstract void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener);
	}

	private final Context mContext;
	private final Browser mBrowser;
	private final float mDensity;
	private final HashMap<String, OnPromptListener> mMap;

	public boolean canceled = false;
	private String syncRtn = null;

	public RexseePrompt(Browser browser) {
		mContext = browser.getContext();
		mDensity = mContext.getResources().getDisplayMetrics().density;
		mBrowser = browser;
		mMap = new HashMap<String, OnPromptListener>();
		mMap.put("prompt", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				showPrompt(argumentsSheet, returnListener);
			}
		});
		mMap.put("3button", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				show3Button(argumentsSheet, returnListener);
			}
		});
		mMap.put("date", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				showDate(argumentsSheet, returnListener);
			}
		});
		mMap.put("time", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				showTime(argumentsSheet, returnListener);
			}
		});
		mMap.put("slider", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				showSlider(argumentsSheet, returnListener);
			}
		});
		mMap.put("rating", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				showRating(argumentsSheet, returnListener);
			}
		});
		mMap.put("radio", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				showRadio(argumentsSheet, returnListener);
			}
		});
		mMap.put("checkbox", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				showCheckBox(argumentsSheet, returnListener);
			}
		});
		mMap.put("menu", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				showMenu(argumentsSheet, returnListener);
			}
		});
		mMap.put("color", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				showColor(argumentsSheet, returnListener);
			}
		});
		mMap.put("country", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				argumentsSheet.selectCities = false;
				showCountryOrCity(argumentsSheet, returnListener);
			}
		});
		mMap.put("city", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				argumentsSheet.selectCities = true;
				showCountryOrCity(argumentsSheet, returnListener);
			}
		});
		mMap.put("sex", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				argumentsSheet.title = RexseeLanguage.TITLE_SELECT;
				argumentsSheet.message = "";
				argumentsSheet.options = RexseeLanguage.SEXES;
				showRadio(argumentsSheet, returnListener);
			}
		});
		mMap.put("symbolicanimal", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				argumentsSheet.title = RexseeLanguage.TITLE_SELECT;
				argumentsSheet.message = "";
				argumentsSheet.options = RexseeLanguage.ANIMALES;
				showRadio(argumentsSheet, returnListener);
			}
		});
		mMap.put("symbolicstar", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				argumentsSheet.title = RexseeLanguage.TITLE_SELECT;
				argumentsSheet.message = "";
				argumentsSheet.options = RexseeLanguage.STARS;
				showRadio(argumentsSheet, returnListener);
			}
		});
		mMap.put("birthday", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				argumentsSheet.title = RexseeLanguage.TITLE_SELECT;
				argumentsSheet.message = "";
				showDate(argumentsSheet, returnListener);
			}
		});
		mMap.put("weekday", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				argumentsSheet.title = RexseeLanguage.TITLE_SELECT;
				argumentsSheet.message = "";
				argumentsSheet.options = RexseeLanguage.WEEKDAYS;
				showRadio(argumentsSheet, returnListener);
			}
		});
		mMap.put("weekdays", new OnPromptListener() {
			@Override
			public void run(PromptArgumentsSheet argumentsSheet, OnPromptReturnListener returnListener) {
				argumentsSheet.title = RexseeLanguage.TITLE_SELECT;
				argumentsSheet.message = "";
				argumentsSheet.options = RexseeLanguage.WEEKDAYS;
				showCheckBox(argumentsSheet, returnListener);
			}
		});
	}

	private int scale(int pixel) {
		return Math.round(mDensity * pixel);
	}
	public String[] list() {
		Object[] arr = mMap.keySet().toArray();
		String[] rtn = new String[arr.length];
		for (int i = 0; i < arr.length; i++) {
			rtn[i] = arr[i].toString();
		}
		return rtn;
	}
	public void add(String key, OnPromptListener listener) {
		mMap.put(key, listener);
	}
	public void run(String type, String arguString, OnPromptReturnListener returnListener) {
		OnPromptListener listener = mMap.get(type.toLowerCase());
		if (listener != null) {
			canceled = false;
			PromptArgumentsSheet argumentsSheet = (new PromptArgumentsSheet()).parseArguments(arguString);
			listener.run(argumentsSheet, returnListener);
		} else {
			error("Prompt type not found.", returnListener);
		}
	}

	private void showRating(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {
		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		final LinearLayout layout = new LinearLayout(mContext);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(scale(10), scale(10), scale(10), scale(10));
		if (argumentsSheet.message.compareTo("") != 0) {
			TextView text = new TextView(mContext);
			text.setPadding(0, scale(10), 0, scale(10));
			layout.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			text.setTextSize(20);
			text.setTextColor(Color.WHITE);
			text.setText(Html.fromHtml(argumentsSheet.message));
		}
		if (argumentsSheet.options == null) {
			int max = (argumentsSheet.max != null) ? Utilities.getInt(argumentsSheet.max[0], 5) : 5;
			int init = (argumentsSheet.defaultValue != null) ? Utilities.getInt(argumentsSheet.defaultValue[0], 5) : 0;
			RatingStars ratingLayout = new RatingStars(mContext, null, init, (max > 5) ? true : false);
			ratingLayout.setId(0);
			layout.addView(ratingLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		} else {
			for (int i = 0; i < argumentsSheet.options.length; i++) {
				int max = (argumentsSheet.max != null && argumentsSheet.max.length > i) ? Utilities.getInt(argumentsSheet.max[i], 5) : 5;
				int init = (argumentsSheet.defaultValue != null && argumentsSheet.defaultValue.length > i) ? Utilities.getInt(argumentsSheet.defaultValue[i], 0) : 0;
				RatingStars ratingLayout = new RatingStars(mContext, argumentsSheet.options[i], init, (max > 5) ? true : false);
				ratingLayout.setId(i);
				layout.addView(ratingLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			}
		}
		ScrollView scroller = new ScrollView(mContext);
		scroller.addView(layout);
		dialog.setView(scroller);
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				if (argumentsSheet.options == null) {
					returnListener.run(String.valueOf(((RatingStars) layout.findViewById(0)).getRating()));
				} else {
					String rtn = "";
					for (int i = 0; i < argumentsSheet.options.length; i++) {
						rtn += (i == 0) ? "" : ",";
						rtn += "\"" + String.valueOf(((RatingStars) layout.findViewById(i)).getRating()) + "\"";
					}
					returnListener.run("[" + rtn + "]");
				}
			}
		});
		if (argumentsSheet.cancelable) dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(null);
			}
		});
		dialog.show();
	}
	private void showCountryOrCity(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {

		final String[][] array = (argumentsSheet.selectCities) ? RexseeLanguage.CITIES.clone() : RexseeLanguage.COUNTRIES.clone();
		final boolean enableFirst = (argumentsSheet.selectCities) ? argumentsSheet.provinceEnable : argumentsSheet.continentEnable;
		final boolean enableSecond = (argumentsSheet.selectCities) ? argumentsSheet.cityEnable : argumentsSheet.countryEnable;

		if (argumentsSheet.selectCities && !argumentsSheet.selectDistrictes) {
			for (int i = 0; i < 6; i++) {
				array[i] = new String[]{array[i][0], array[i][0]};
			}
		}

		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		LinearLayout layout = new LinearLayout(mContext);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(scale(10), scale(10), scale(10), scale(10));
		if (argumentsSheet.message.compareTo("") != 0) {
			TextView text = new TextView(mContext);
			text.setPadding(0, 0, 0, scale(10));
			text.setTextSize(20);
			text.setTextColor(Color.WHITE);
			text.setText(Html.fromHtml(argumentsSheet.message));
			layout.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		}
		LinearLayout provinceLayout = new LinearLayout(mContext);
		provinceLayout.setOrientation(LinearLayout.HORIZONTAL);
		provinceLayout.setGravity(Gravity.CENTER_VERTICAL);
		final TextView provinceText = new TextView(mContext);
		provinceText.setPadding(0, 0, 0, scale(10));
		provinceText.setTextSize(16);
		provinceText.setTextColor(Color.WHITE);
		provinceText.setText(array[0][0]);
		provinceLayout.addView(provinceText, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 2));
		final Button provinceButton = new Button(mContext);
		provinceButton.setText(RexseeLanguage.TITLE_SELECT);
		provinceLayout.addView(provinceButton, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		layout.addView(provinceLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		LinearLayout cityLayout = new LinearLayout(mContext);
		cityLayout.setOrientation(LinearLayout.HORIZONTAL);
		cityLayout.setGravity(Gravity.CENTER_VERTICAL);
		final TextView cityText = new TextView(mContext);
		cityText.setPadding(0, 0, 0, scale(10));
		cityText.setTextSize(16);
		cityText.setTextColor(Color.WHITE);
		cityText.setText(array[0][1]);
		cityLayout.addView(cityText, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 2));
		final Button cityButton = new Button(mContext);
		cityButton.setText(RexseeLanguage.TITLE_SELECT);
		cityLayout.addView(cityButton, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		layout.addView(cityLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		provinceButton.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
			@Override
			public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
				for (int i = 0; i < array.length; i++) {
					MenuItem item = menu.add(array[i][0]);
					final String firstCity = array[i][1];
					item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
						@Override
						public boolean onMenuItemClick(MenuItem item) {
							provinceText.setText(item.getTitle().toString());
							cityText.setText(firstCity);
							return false;
						}
					});
				}
				menu.setHeaderTitle(argumentsSheet.title);
			}
		});
		provinceButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				v.showContextMenu();
			}
		});
		cityButton.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
			@Override
			public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
				String province = provinceText.getText().toString();
				String[] cities = null;
				for (int i = 0; i < array.length; i++) {
					if (array[i][0].equalsIgnoreCase(province)) {
						cities = array[i];
						break;
					}
				}
				if (cities == null) {
					error("Cities for " + province + "not found.", returnListener);
				} else {
					for (int i = 1; i < cities.length; i++) {
						MenuItem item = menu.add(cities[i]);
						item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
							@Override
							public boolean onMenuItemClick(MenuItem item) {
								cityText.setText(item.getTitle().toString());
								return false;
							}
						});
					}
				}
				menu.setHeaderTitle(province);
			}
		});
		cityButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				v.showContextMenu();
			}
		});
		if (argumentsSheet.defaultValue != null) {
			for (int i = 0; i < array.length; i++) {
				if (argumentsSheet.defaultValue[0].startsWith(array[i][0])) {
					provinceText.setText(array[i][0]);
					cityText.setText(array[i][1]);
					String city = argumentsSheet.defaultValue[0].substring(array[i][0].length());
					for (int j = 0; j < array[i].length; j++) {
						if (city.equalsIgnoreCase(array[i][j])) {
							cityText.setText(city);
							break;
						}
					}
					break;
				}
			}
		}
		if (!enableFirst) {
			provinceLayout.setVisibility(View.GONE);
		}
		if (!enableSecond) {
			cityLayout.setVisibility(View.GONE);
		}
		ScrollView scroller = new ScrollView(mContext);
		scroller.addView(layout);
		dialog.setView(scroller);
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				String rtn = "";
				if (enableFirst) {
					rtn += "\"" + provinceText.getText().toString() + "\"";
				}
				if (enableFirst && enableSecond) {
					rtn += ",";
				}
				if (enableSecond) {
					rtn += "\"" + cityText.getText().toString() + "\"";
				}
				returnListener.run("[" + rtn + "]");
			}
		});
		if (argumentsSheet.cancelable) dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(null);
			}
		});
		dialog.show();
	}
	private void showColor(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {

		final String[][] colors = {{"#312F9D", "#0000FF", "#0066FF", "#00999A", "#009CD1", "#7ECEFF", "#00FFFF", "#B4FDFF"}, {"#003168", "#006400", "#439A00", "#009864", "#00FF00", "#00CC5D", "#4CFE53", "#00FF9C"}, {"#006E69", "#636727", "#CFCD00", "#B4FF57", "#FF9900", "#FFCD99", "#FFFF00", "#FEFF94"}, {"#752F00", "#AF0132", "#B13100", "#960000", "#C1001D", "#FF0000", "#FF2E00", "#FF0069"}, {"#780068", "#7000D4", "#B32FFF", "#B4009D", "#FF00FF", "#FF66FF", "#FF679D", "#FFCDFF"}, {"#000000", "#333333", "#666666", "#888888", "#aaaaaa", "#cccccc", "#e7e7e7", "#ffffff"}};
		int defaultColor = Color.BLACK;

		if (argumentsSheet.defaultValue != null) {
			try {
				defaultColor = Color.parseColor(argumentsSheet.defaultValue[0]);
			} catch (Exception e) {
				error("Default Value Error: " + e.getLocalizedMessage(), returnListener);
				return;
			}
		}
		String defaultRgbValue = Color.red(defaultColor) + "," + Color.green(defaultColor) + "," + Color.blue(defaultColor);
		String red = String.valueOf(Integer.toHexString(Color.red(defaultColor)));
		String green = String.valueOf(Integer.toHexString(Color.green(defaultColor)));
		String blue = String.valueOf(Integer.toHexString(Color.blue(defaultColor)));
		if (red.length() == 1) red = "0" + red;
		if (green.length() == 1) green = "0" + green;
		if (blue.length() == 1) blue = "0" + blue;
		String defaultHexValue = "#" + red + green + blue;
		final AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		LinearLayout layout = new LinearLayout(mContext);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(scale(5), 0, 0, scale(10));
		if (argumentsSheet.message.compareTo("") != 0) {
			TextView text = new TextView(mContext);
			text.setPadding(scale(15), scale(15), 0, scale(15));
			text.setTextSize(20);
			text.setTextColor(Color.WHITE);
			text.setText(Html.fromHtml(argumentsSheet.message));
			layout.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		}
		LinearLayout header = new LinearLayout(mContext);
		header.setOrientation(LinearLayout.HORIZONTAL);
		header.setPadding(scale(15), 0, scale(3), 0);
		header.setGravity(Gravity.CENTER_VERTICAL);
		LinearLayout demoBorder = new LinearLayout(mContext);
		demoBorder.setGravity(Gravity.CENTER);
		demoBorder.setBackgroundColor(Color.WHITE);
		final ImageView demo = new ImageView(mContext);
		demo.setImageDrawable(new ColorDrawable(defaultColor));
		demoBorder.addView(demo, new LinearLayout.LayoutParams(scale(118), scale(48)));
		header.addView(demoBorder, new LinearLayout.LayoutParams(scale(120), scale(50)));
		final LinearLayout values = new LinearLayout(mContext);
		values.setOrientation(LinearLayout.VERTICAL);
		values.setGravity(Gravity.CENTER_VERTICAL);
		final TextView rgbValue = new TextView(mContext);
		rgbValue.setMinWidth(scale(125));
		rgbValue.setPadding(scale(20), scale(10), scale(10), scale(10));
		rgbValue.setText(defaultRgbValue);
		values.addView(rgbValue, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		final TextView hexValue = new TextView(mContext);
		hexValue.setPadding(scale(20), 0, scale(10), scale(10));
		hexValue.setText(defaultHexValue);
		values.addView(hexValue, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		header.addView(values, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		layout.addView(header, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		final LinearLayout table = new LinearLayout(mContext);
		table.setOrientation(LinearLayout.VERTICAL);
		table.setGravity(Gravity.CENTER_HORIZONTAL);
		table.setPadding(scale(12), scale(12), scale(12), scale(12));
		for (int i = 0; i < colors.length; i++) {
			LinearLayout row = new LinearLayout(mContext);
			row.setOrientation(LinearLayout.HORIZONTAL);
			for (int j = 0; j < colors[i].length; j++) {
				final int color = Color.parseColor(colors[i][j]);
				final LinearLayout cell = new LinearLayout(mContext);
				cell.setGravity(Gravity.CENTER);
				ImageView v = new ImageView(mContext);
				v.setImageDrawable(new ColorDrawable(color));
				v.setClickable(true);
				v.setOnClickListener(new View.OnClickListener() {
					@Override
					public void onClick(View v) {
						for (int k = 0; k < table.getChildCount(); k++) {
							LinearLayout r =
									(LinearLayout) table.getChildAt(k);
							for (int l = 0; l < r.getChildCount(); l++) {
								r.getChildAt(l).setBackgroundColor(Color.DKGRAY);
							}
						}
						cell.setBackgroundColor(Color.WHITE);
						demo.setImageDrawable(new ColorDrawable(color));
						rgbValue.setText(Color.red(color) + "," + Color.green(color) + "," + Color.blue(color));
						String red =
								String.valueOf(Integer.toHexString(Color.red(color)));
						String green =
								String.valueOf(Integer.toHexString(Color.green(color)));
						String blue =
								String.valueOf(Integer.toHexString(Color.blue(color)));
						if (red.length() == 1) red = "0" + red;
						if (green.length() == 1) green = "0" + green;
						if (blue.length() == 1) blue = "0" + blue;
						hexValue.setText("#" + red + green + blue);
					}
				});
				cell.addView(v, new LinearLayout.LayoutParams(scale(22), scale(22)));
				row.addView(cell, new LinearLayout.LayoutParams(scale(30), scale(30)));
			}
			table.addView(row, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		}
		layout.addView(table, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		final LinearLayout slider = new LinearLayout(mContext);
		slider.setOrientation(LinearLayout.VERTICAL);
		slider.setVisibility(View.GONE);
		slider.setPadding(scale(15), scale(20), scale(15), scale(25));
		final Slider redBar = new Slider(mContext, "R: ", 0, 255, Color.red(defaultColor), new Slider.OnSliderChangeListener() {
			@Override
			public void run(int progress) {
				progress = progress * 255 / 100;
				String[] rgb = rgbValue.getText().toString().split(",");
				rgbValue.setText(progress + "," + rgb[1] + "," + rgb[2]);
				String red = String.valueOf(Integer.toHexString(progress));
				if (red.length() == 1) red = "0" + red;
				String hex = "#" + red + hexValue.getText().toString().substring(3);
				hexValue.setText(hex);
				demo.setImageDrawable(new ColorDrawable(Color.parseColor(hex)));
			}
		});
		final Slider greenBar = new Slider(mContext, "G: ", 0, 255, Color.green(defaultColor), new Slider.OnSliderChangeListener() {
			@Override
			public void run(int progress) {
				progress = progress * 255 / 100;
				String[] rgb = rgbValue.getText().toString().split(",");
				rgbValue.setText(rgb[0] + "," + progress + "," + rgb[2]);
				String green = String.valueOf(Integer.toHexString(progress));
				if (green.length() == 1) green = "0" + green;
				String oHex = hexValue.getText().toString();
				String hex = oHex.substring(0, 3) + green + oHex.substring(5);
				hexValue.setText(hex);
				demo.setImageDrawable(new ColorDrawable(Color.parseColor(hex)));
			}
		});
		final Slider blueBar = new Slider(mContext, "B: ", 0, 255, Color.blue(defaultColor), new Slider.OnSliderChangeListener() {
			@Override
			public void run(int progress) {
				progress = progress * 255 / 100;
				String[] rgb = rgbValue.getText().toString().split(",");
				rgbValue.setText(rgb[0] + "," + rgb[1] + "," + progress);
				String blue = String.valueOf(Integer.toHexString(progress));
				if (blue.length() == 1) blue = "0" + blue;
				String hex = hexValue.getText().toString().substring(0, 5) + blue;
				hexValue.setText(hex);
				demo.setImageDrawable(new ColorDrawable(Color.parseColor(hex)));
			}
		});
		slider.addView(redBar, new Slider.LayoutParams(Slider.LayoutParams.FILL_PARENT, Slider.LayoutParams.WRAP_CONTENT));
		slider.addView(greenBar, new Slider.LayoutParams(Slider.LayoutParams.FILL_PARENT, Slider.LayoutParams.WRAP_CONTENT));
		slider.addView(blueBar, new Slider.LayoutParams(Slider.LayoutParams.FILL_PARENT, Slider.LayoutParams.WRAP_CONTENT));
		layout.addView(slider, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		final RadioGroup footer = new RadioGroup(mContext);
		footer.setOrientation(LinearLayout.HORIZONTAL);
		footer.setGravity(Gravity.CENTER_HORIZONTAL);
		RadioButton radio0 = new RadioButton(mContext);
		radio0.setId(0);
		radio0.setPadding(scale(40), 0, scale(15), 0);
		radio0.setText(RexseeLanguage.TITLE_COLOR_PICKER);
		radio0.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
				table.setVisibility((arg1) ? View.VISIBLE : View.GONE);
				if (arg1) {
					for (int k = 0; k < table.getChildCount(); k++) {
						LinearLayout r = (LinearLayout) table.getChildAt(k);
						for (int l = 0; l < r.getChildCount(); l++) {
							r.getChildAt(l).setBackgroundColor(Color.DKGRAY);
						}
					}
				}
			}
		});
		RadioButton radio1 = new RadioButton(mContext);
		radio1.setId(1);
		radio1.setPadding(scale(40), 0, scale(10), 0);
		radio1.setText(RexseeLanguage.TITLE_COLOR_SLIDER);
		radio1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(CompoundButton arg0, boolean arg1) {
				slider.setVisibility((arg1) ? View.VISIBLE : View.GONE);
				if (arg1) {
					String[] rgb = rgbValue.getText().toString().split(",");
					redBar.setValue(rgb[0]);
					greenBar.setValue(rgb[1]);
					blueBar.setValue(rgb[2]);
				}
			}
		});
		footer.addView(radio0);
		footer.addView(radio1);
		footer.check(0);
		layout.addView(footer, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		ScrollView scroller = new ScrollView(mContext);
		scroller.setHorizontalFadingEdgeEnabled(false);
		scroller.setVerticalFadingEdgeEnabled(false);
		scroller.addView(layout);
		dialog.setView(scroller);
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				returnListener.run("{\"hex\":\"" + hexValue.getText().toString() + "\",\"rgb\":\"" + rgbValue.getText().toString() + "\"}");
			}
		});
		if (argumentsSheet.cancelable) {
			dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					returnListener.run(null);
				}
			});
		}
		dialog.show();
	}
	private void showMenu(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {
		if (argumentsSheet.options == null) {
			error("No options found for menu dialog.", returnListener);
			return;
		}
		PopMenu popMenu = new PopMenu(mBrowser, "", "label:" + argumentsSheet.title + ";window-cancelable:" + ((argumentsSheet.cancelable) ? "true" : "false") + ";");
		for (int i = 0; i < argumentsSheet.options.length; i++) {
			final String itemText = argumentsSheet.options[i];
			Runnable runnable = new Runnable() {
				@Override
				public void run() {
					returnListener.run(itemText);
				}
			};
			popMenu.add(new PopMenuItem(mContext, "options", runnable, "label:" + itemText + ";"));
		}
		popMenu.cancelRunnable = new Runnable() {
			@Override
			public void run() {
				returnListener.run(null);
			}
		};
		mBrowser.menu.open(popMenu);
	}
	private void showCheckBox(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {
		if (argumentsSheet.options == null) {
			error("No options found for checkbox dialog.", returnListener);
			return;
		}
		GradientDrawable lineDrawable = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, new int[]{Color.parseColor("#888888"), Color.parseColor("#AAAAAA"), Color.WHITE});
		final AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		dialog.setInverseBackgroundForced(true);
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		LinearLayout layout = new LinearLayout(mContext);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(scale(10), 0, scale(10), 0);
		layout.setMinimumWidth(scale(280));
		if (argumentsSheet.message.compareTo("") != 0) {
			TextView text = new TextView(mContext);
			layout.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			text.setPadding(0, scale(15), 0, scale(15));
			text.setTextSize(20);
			text.setTextColor(Color.BLACK);
			text.setText(Html.fromHtml(argumentsSheet.message));
			ImageView line = new ImageView(mContext);
			line.setImageDrawable(lineDrawable);
			layout.addView(line, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, 1));
		}
		final LinearLayout checkboxes = new LinearLayout(mContext);
		checkboxes.setOrientation(LinearLayout.VERTICAL);
		if (argumentsSheet.selectAll) {
			LinearLayout footerLayout = new LinearLayout(mContext);
			footerLayout.setOrientation(LinearLayout.HORIZONTAL);
			footerLayout.setPadding(0, scale(5), 0, 0);
			Button yesButton = new Button(mContext);
			Button noButton = new Button(mContext);
			yesButton.setText(RexseeLanguage.ACTION_SELECT_ALL);
			yesButton.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					for (int i = 0; i < argumentsSheet.options.length; i++) {
						CheckBox c = (CheckBox) checkboxes.findViewById(i);
						c.setChecked(true);
					}
				}
			});
			noButton.setText(RexseeLanguage.ACTION_UNSELECT_ALL);
			noButton.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					for (int i = 0; i < argumentsSheet.options.length; i++) {
						CheckBox c = (CheckBox) checkboxes.findViewById(i);
						c.setChecked(false);
					}
				}
			});
			footerLayout.addView(yesButton, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1));
			footerLayout.addView(noButton, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 1));
			layout.addView(footerLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			ImageView line = new ImageView(mContext);
			line.setImageDrawable(lineDrawable);
			line.setClickable(false);
			layout.addView(line, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, 1));
		}
		for (int i = 0; i < argumentsSheet.options.length; i++) {
			if (i != 0) {
				ImageView line = new ImageView(mContext);
				line.setImageDrawable(lineDrawable);
				line.setClickable(false);
				checkboxes.addView(line, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, 1));
			}
			CheckBox b = new CheckBox(mContext);
			b.setId(i);
			b.setPadding(scale(40), scale(10), scale(10), scale(10));
			b.setMinimumHeight(scale(60));
			b.setTextSize(20);
			b.setTextColor(Color.BLACK);
			b.setText(Html.fromHtml(argumentsSheet.options[i]));
			b.setChecked((argumentsSheet.defaultValue != null && argumentsSheet.defaultValue.length > i && argumentsSheet.defaultValue[i].equalsIgnoreCase("true")) ? true : false);
			checkboxes.addView(b);
		}
		layout.addView(checkboxes, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		ScrollView scroller = new ScrollView(mContext);
		scroller.setVerticalFadingEdgeEnabled(false);
		scroller.setHorizontalFadingEdgeEnabled(false);
		scroller.addView(layout);
		dialog.setView(scroller);
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.dismiss();
				String rtn = "";
				for (int i = 0; i < argumentsSheet.options.length; i++) {
					CheckBox c = (CheckBox) checkboxes.findViewById(i);
					if (c.isChecked()) {
						if (!rtn.equals("")) rtn += ",";
						rtn += "\"" + argumentsSheet.options[i] + "\"";
					}
				}
				returnListener.run("[" + rtn + "]");
			}
		});
		if (argumentsSheet.cancelable) {
			dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					returnListener.run(null);
				}
			});
		}
		dialog.show();
	}
	private void showRadio(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {
		if (argumentsSheet.options == null) {
			error("No options found for radio dialog.", returnListener);
			return;
		}
		GradientDrawable lineDrawable = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, new int[]{Color.parseColor("#888888"), Color.parseColor("#AAAAAA"), Color.WHITE});
		final AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		dialog.setInverseBackgroundForced(true);
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		LinearLayout layout = new LinearLayout(mContext);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(scale(10), 0, scale(10), 0);
		layout.setMinimumWidth(scale(280));
		if (argumentsSheet.message.compareTo("") != 0) {
			TextView text = new TextView(mContext);
			layout.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			text.setPadding(0, scale(15), 0, scale(15));
			text.setTextSize(20);
			text.setTextColor(Color.BLACK);
			text.setText(Html.fromHtml(argumentsSheet.message));
			ImageView line = new ImageView(mContext);
			line.setImageDrawable(lineDrawable);
			layout.addView(line, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, 1));
		}
		final RadioGroup radios = new RadioGroup(mContext);
		int defaultId = 0;
		for (int i = 0; i < argumentsSheet.options.length; i++) {
			if (i != 0) {
				ImageView line = new ImageView(mContext);
				line.setImageDrawable(lineDrawable);
				radios.addView(line, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, 1));
			}
			RadioButton b = new RadioButton(mContext);
			b.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			b.setPadding(scale(40), scale(10), scale(10), scale(10));
			b.setMinimumHeight(scale(60));
			b.setTextSize(20);
			b.setTextColor(Color.BLACK);
			b.setText(Html.fromHtml(argumentsSheet.options[i]));
			b.setId(i);
			radios.addView(b);
			if (argumentsSheet.defaultValue != null) {
				if (argumentsSheet.defaultValue[0].equals(argumentsSheet.options[i])) defaultId = i;
			}
		}
		radios.check(defaultId);
		layout.addView(radios, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		if (argumentsSheet.returnImmediately) {
			radios.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
				@Override
				public void onCheckedChanged(RadioGroup group, int checkedId) {
					dialog.dismiss();
					returnListener.run(argumentsSheet.options[checkedId]);
				}
			});
		}
		ScrollView scroller = new ScrollView(mContext);
		scroller.setVerticalFadingEdgeEnabled(false);
		scroller.setHorizontalFadingEdgeEnabled(false);
		scroller.addView(layout);
		dialog.setView(scroller);
		if (!argumentsSheet.returnImmediately) {
			dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					dialog.dismiss();
					returnListener.run(argumentsSheet.options[radios.getCheckedRadioButtonId()]);
				}
			});
			if (argumentsSheet.cancelable) {
				dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
					@Override
					public void onClick(DialogInterface dialog, int which) {
						dialog.dismiss();
						returnListener.run(null);
					}
				});
			}
		}
		dialog.show();
	}
	private void showSlider(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {
		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		final LinearLayout layout = new LinearLayout(mContext);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(scale(10), scale(10), scale(10), scale(10));
		if (argumentsSheet.message.compareTo("") != 0) {
			TextView text = new TextView(mContext);
			layout.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			text.setPadding(0, 0, 0, scale(10));
			text.setTextSize(20);
			text.setTextColor(Color.WHITE);
			text.setText(Html.fromHtml(argumentsSheet.message));
		}
		if (argumentsSheet.options == null) {
			int begin = (argumentsSheet.min != null) ? Utilities.getInt(argumentsSheet.min[0], 0) : 0;
			int end = (argumentsSheet.max != null) ? Utilities.getInt(argumentsSheet.max[0], 100) : 100;
			int value = (argumentsSheet.defaultValue != null) ? Utilities.getInt(argumentsSheet.defaultValue[0], 0) : 0;
			Slider slider = new Slider(mContext, null, begin, end, value, null);
			slider.setId(0);
			layout.addView(slider, new Slider.LayoutParams(Slider.LayoutParams.FILL_PARENT, Slider.LayoutParams.WRAP_CONTENT));
		} else {
			for (int i = 0; i < argumentsSheet.options.length; i++) {
				int begin = (argumentsSheet.min != null && argumentsSheet.min.length > i) ? Utilities.getInt(argumentsSheet.min[i], 0) : 0;
				int end = (argumentsSheet.max != null && argumentsSheet.max.length > i) ? Utilities.getInt(argumentsSheet.max[i], 100) : 100;
				int value = (argumentsSheet.defaultValue != null && argumentsSheet.defaultValue.length > i) ? Utilities.getInt(argumentsSheet.defaultValue[i], 0) : 0;
				Slider slider = new Slider(mContext, argumentsSheet.options[i], begin, end, value, null);
				slider.setId(i);
				layout.addView(slider, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			}
		}
		ScrollView scroller = new ScrollView(mContext);
		scroller.addView(layout);
		dialog.setView(scroller);
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				if (argumentsSheet.options == null) {
					returnListener.run(((Slider) layout.findViewById(0)).getValue());
				} else {
					String rtn = "";
					for (int i = 0; i < argumentsSheet.options.length; i++) {
						rtn += (i == 0) ? "" : ",";
						rtn += "\"" + ((Slider) layout.findViewById(i)).getValue() + "\"";
					}
					returnListener.run("[" + rtn + "]");
				}
			}
		});
		if (argumentsSheet.cancelable) dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(null);
			}
		});
		dialog.show();
	}
	private void showPrompt(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {
		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		final LinearLayout layout = new LinearLayout(mContext);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(scale(10), scale(10), scale(10), scale(10));
		if (argumentsSheet.message.compareTo("") != 0) {
			TextView text = new TextView(mContext);
			layout.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			text.setPadding(0, 0, 0, scale(10));
			text.setTextSize(20);
			text.setTextColor(Color.WHITE);
			text.setText(Html.fromHtml(argumentsSheet.message));
		}
		if (argumentsSheet.options == null) {
			EditText editBox = new EditText(mContext);
			editBox.setMinHeight(24);
			layout.addView(editBox, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			editBox.setId(0);
			if (argumentsSheet.selectAll) editBox.setSelectAllOnFocus(true);
			editBox.setSingleLine((argumentsSheet.singleLine != null && argumentsSheet.singleLine[0].equalsIgnoreCase("false")) ? false : true);
			int maxLength = (argumentsSheet.max != null) ? Utilities.getInt(argumentsSheet.max[0], -1) : -1;
			if (maxLength > 0) {
				InputFilter[] filter = new InputFilter[1];
				filter[0] = new InputFilter.LengthFilter(maxLength);
				editBox.setFilters(filter);
			}
			if (argumentsSheet.inputType != null) editBox.setInputType(PromptArgumentsSheet.getInputType(argumentsSheet.inputType[0]));
			editBox.setText((argumentsSheet.defaultValue != null) ? argumentsSheet.defaultValue[0] : "");
			editBox.requestFocus();
		} else {
			for (int i = 0; i < argumentsSheet.options.length; i++) {
				LinearLayout editLayout = new LinearLayout(mContext);
				TextView editTitle = new TextView(mContext);
				EditText editBox = new EditText(mContext);
				editBox.setMinHeight(24);
				editLayout.addView(editTitle, new LinearLayout.LayoutParams(scale(95), LinearLayout.LayoutParams.WRAP_CONTENT));
				editLayout.addView(editBox, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
				layout.addView(editLayout, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
				editLayout.setOrientation(LinearLayout.HORIZONTAL);
				editLayout.setGravity(Gravity.CENTER_VERTICAL);
				editTitle.setTextSize(18);
				editTitle.setTextColor(Color.WHITE);
				editTitle.setText(Html.fromHtml(argumentsSheet.options[i]));
				editBox.setId(i);
				if (argumentsSheet.selectAll) editBox.setSelectAllOnFocus(true);
				editBox.setSingleLine((argumentsSheet.singleLine != null && argumentsSheet.singleLine.length > i && argumentsSheet.singleLine[i].equalsIgnoreCase("false")) ? false : true);
				int maxLength = (argumentsSheet.max != null && argumentsSheet.max.length > i) ? Utilities.getInt(argumentsSheet.max[i], -1) : -1;
				if (maxLength > 0) {
					InputFilter[] filter = new InputFilter[1];
					filter[0] = new InputFilter.LengthFilter(maxLength);
					editBox.setFilters(filter);
				}
				if (argumentsSheet.inputType != null && argumentsSheet.inputType.length > i) editBox.setInputType(PromptArgumentsSheet.getInputType(argumentsSheet.inputType[i]));
				editBox.setHint(Html.fromHtml(argumentsSheet.options[i]).toString());
				editBox.setHintTextColor(Color.parseColor("#AAAAAA"));
				editBox.setText((argumentsSheet.defaultValue != null && argumentsSheet.defaultValue.length > i) ? argumentsSheet.defaultValue[i] : "");
				if (i == 0) editBox.requestFocus();
			}
		}
		ScrollView scroller = new ScrollView(mContext);
		scroller.addView(layout);
		dialog.setView(scroller);
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				if (argumentsSheet.options == null) {
					returnListener.run(((TextView) layout.findViewById(0)).getText().toString());
				} else {
					String rtn = "";
					for (int i = 0; i < argumentsSheet.options.length; i++) {
						rtn += (i == 0) ? "" : ",";
						rtn += "\"" + ((TextView) layout.findViewById(i)).getText().toString() + "\"";
					}
					returnListener.run("[" + rtn + "]");
				}
			}
		});
		if (argumentsSheet.cancelable) dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(null);
			}
		});
		dialog.show();
	}
	private void show3Button(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {
		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		dialog.setMessage(Html.fromHtml(argumentsSheet.message));
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		String[] buttons = argumentsSheet.options;
		final String buttonPositive = (buttons != null && buttons.length >= 1) ? buttons[0] : "";
		final String buttonNeutral = (buttons != null && buttons.length >= 2) ? buttons[1] : "";
		final String buttonNegative = (buttons != null && buttons.length >= 3) ? buttons[2] : "";
		if (buttonPositive != "") dialog.setButton(DialogInterface.BUTTON_POSITIVE, Html.fromHtml(buttonPositive), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(buttonPositive);
			}
		});
		if (buttonNeutral != "") dialog.setButton(DialogInterface.BUTTON_NEUTRAL, Html.fromHtml(buttonNeutral), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(buttonNeutral);
			}
		});
		if (buttonNegative != "") dialog.setButton(DialogInterface.BUTTON_NEGATIVE, Html.fromHtml(buttonNegative), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(buttonNegative);
			}
		});
		dialog.show();
	}
	private void showDate(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {
		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		LinearLayout layout = new LinearLayout(mContext);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(scale(10), scale(10), scale(10), scale(10));
		if (argumentsSheet.message.compareTo("") != 0) {
			TextView text = new TextView(mContext);
			layout.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			text.setPadding(0, 0, 0, scale(10));
			text.setTextSize(20);
			text.setTextColor(Color.WHITE);
			text.setText(Html.fromHtml(argumentsSheet.message));
		}
		final DatePicker picker = new DatePicker(mContext);
		layout.addView(picker, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		picker.init(argumentsSheet.calendar.get(Calendar.YEAR), argumentsSheet.calendar.get(Calendar.MONTH), argumentsSheet.calendar.get(Calendar.DATE), new DatePicker.OnDateChangedListener() {
			@Override
			public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
				argumentsSheet.calendar.set(Calendar.YEAR, year);
				argumentsSheet.calendar.set(Calendar.MONTH, monthOfYear);
				argumentsSheet.calendar.set(Calendar.DATE, dayOfMonth);
			}
		});
		try {
			ViewGroup pickerGroup = (ViewGroup) picker.getChildAt(0);
			Locale locale = mContext.getResources().getConfiguration().locale;
			String lang = locale.getLanguage().toLowerCase();
			if (lang.equals("zh")) {
				pickerGroup.getChildAt(0).setEnabled((argumentsSheet.yearEnable) ? true : false);
				pickerGroup.getChildAt(1).setEnabled((argumentsSheet.monthEnable) ? true : false);
				pickerGroup.getChildAt(2).setEnabled((argumentsSheet.dayEnable) ? true : false);
			} else {
				pickerGroup.getChildAt(2).setEnabled((argumentsSheet.yearEnable) ? true : false);
				pickerGroup.getChildAt(0).setEnabled((argumentsSheet.monthEnable) ? true : false);
				pickerGroup.getChildAt(1).setEnabled((argumentsSheet.dayEnable) ? true : false);
			}
		} catch (Exception e) {
		}
		ScrollView scroller = new ScrollView(mContext);
		scroller.addView(layout);
		dialog.setView(scroller);
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				picker.clearFocus();
				Date date = argumentsSheet.calendar.getTime();
				String rtn = "{";
				rtn += (argumentsSheet.yearEnable) ? "\"year\":" + (new SimpleDateFormat("yyyy")).format(date) : "\"year\":-1";
				rtn += (argumentsSheet.monthEnable) ? ",\"month\":" + (new SimpleDateFormat("M")).format(date) : ",\"month\":-1";
				rtn += (argumentsSheet.dayEnable) ? ",\"day\":" + (new SimpleDateFormat("d")).format(date) : ",\"day\":-1";
				rtn += (argumentsSheet.dayEnable) ? ",\"week\":\"" + (new SimpleDateFormat("E")).format(date) + "\"" : ",\"week\":\"\"";
				rtn += "}";
				returnListener.run(rtn);
			}
		});
		if (argumentsSheet.cancelable) dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(null);
			}
		});
		dialog.show();
	}
	private void showTime(final PromptArgumentsSheet argumentsSheet, final OnPromptReturnListener returnListener) {
		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(Html.fromHtml(argumentsSheet.title));
		dialog.setCancelable(false);
		dialog.setOnKeyListener(new Dialog.OnKeyListener() {
			@Override
			public boolean onKey(DialogInterface arg0, int arg1, KeyEvent arg2) {
				if (arg1 == KeyEvent.KEYCODE_SEARCH) return true;
				else return false;
			}
		});
		LinearLayout layout = new LinearLayout(mContext);
		layout.setOrientation(LinearLayout.VERTICAL);
		layout.setPadding(scale(10), scale(10), scale(10), scale(10));
		if (argumentsSheet.message.compareTo("") != 0) {
			TextView text = new TextView(mContext);
			layout.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
			text.setPadding(0, 0, 0, scale(10));
			text.setTextSize(20);
			text.setTextColor(Color.WHITE);
			text.setText(Html.fromHtml(argumentsSheet.message));
		}
		final TextView header = new TextView(mContext);
		final TimePicker picker = new TimePicker(mContext);
		layout.addView(header, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		layout.addView(picker, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
		header.setPadding(scale(4), 0, 0, scale(10));
		header.setTextSize(16);
		header.setTextColor(Color.WHITE);
		header.setText(argumentsSheet.getTime());
		picker.setCurrentHour(argumentsSheet.calendar.get(Calendar.HOUR_OF_DAY));
		picker.setCurrentMinute(argumentsSheet.calendar.get(Calendar.MINUTE));
		picker.setIs24HourView((argumentsSheet.hour24) ? true : false);
		picker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
			@Override
			public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
				argumentsSheet.calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
				argumentsSheet.calendar.set(Calendar.MINUTE, minute);
				header.setText(argumentsSheet.getTime());
			}
		});
		ScrollView scroller = new ScrollView(mContext);
		scroller.addView(layout);
		dialog.setView(scroller);
		dialog.setButton(DialogInterface.BUTTON_NEGATIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				picker.clearFocus();
				returnListener.run(argumentsSheet.getTime());
			}
		});
		if (argumentsSheet.cancelable) dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.cancel), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(null);
			}
		});
		dialog.show();
	}
	private void error(final String message, final OnPromptReturnListener returnListener) {
		AlertDialog dialog = new AlertDialog.Builder(mContext).create();
		dialog.setIcon(mBrowser.application.icon);
		dialog.setTitle(RexseeLanguage.TITLE_ERROR);
		dialog.setMessage(message);
		dialog.setCancelable(false);
		dialog.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getResources().getString(android.R.string.ok), new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int whichButton) {
				dialog.dismiss();
				returnListener.run(null);
			}
		});
		dialog.show();
	}

	//JavaScript Interface
	public boolean isCanceled() {
		return canceled;
	}
	public String prompt(final String type, final String argu) {
		Thread thread = new Thread() {
			@Override
			public void run() {
				((Activity) mContext).runOnUiThread(new Runnable() {
					@Override
					public void run() {
						RexseePrompt.this.run(type, argu, new RexseePrompt.OnPromptReturnListener() {
							@Override
							public void run(String rtn) {
								canceled = (rtn == null) ? true : false;
								syncRtn = (rtn == null) ? "" : rtn;
							}
						});
					}
				});
			}
		};
		syncRtn = null;
		thread.start();
		while (syncRtn == null) {
			try {
				Thread.sleep(100);
			} catch (Exception e) {
			}
		}
		thread = null;
		return syncRtn;
	}

}
